import { getDeviceShadow, getToken, sendDevicesMessage } from '../api/API';
import { generateShortId4 } from '../api/generateShortId4';
import type { DeviceShadowData } from '../api/Type/DeviceShadow';
import type {
  DeviceActionType,
  MessageResultResponse,
  MessageResultResponseErr,
  postDevicesMessageRequest
} from '../api/Type/DevicesMessage';

class DeviceShadowManager {
  private projectId = '77ae7ee7a2fd4e1993982ae88b9a2ff6';
  private deviceId = '684134b3d582f200182e366d_000001';
  private info: DeviceShadowData | null = null;
  // 是否准备好数据参数
  private readyPromise: Promise<void>;
  // 循环检测任务
  private t: number = 0
  private static instance: DeviceShadowManager = new DeviceShadowManager();

  private constructor() {
    this.readyPromise = this.init()
  }

  private async init() {
    await this.update()
    this.detectionCycle()
  }

  public async ready(): Promise<void> {
    return this.readyPromise
  }

  /** 获取单例实例 */
  public static getInstance(): DeviceShadowManager {
    return DeviceShadowManager.instance
  }

  /**
   * 设置循环获取数据(现在是10秒获取一次数据)
   */
  private detectionCycle() {
    this.t = setInterval(async () => {
      console.log("开始检测设备影子数据")
      await this.update()
    }, 10000)
  }
  public stopDetectionCycle() {
    if (this.t) {
      clearInterval(this.t)
      this.t = 0
    }
  }

  /** 更新设备影子信息（异步） */
  public async update(): Promise<void> {

    const data = await getDeviceShadow(this.projectId, this.deviceId);
    if ('error_code' in data) {
      await getToken() // 如果获取失败，尝试重新获取token
      console.error("获取设备影子数据失败，尝试重新获取token");
      return this.update(); // 重新尝试获取数据
    }
    this.info = data.shadow[0].reported.properties;

  }

  /**
   * 向指定设备发送一条控制消息。
   *
   * @param {DeviceActionType} message - 要发送的设备控制指令，例如 `DeviceAction.LOCK_OFF`。
   * @returns {Promise<MessageResultResponse | MessageResultResponseErr>} 返回一个 Promise，成功时为响应数据，失败时为错误信息。
   *
   * @example
   * DeviceShadowManagerInstance.sendMessage(DeviceAction.LOCK_OFF).then((response) => {
   *   console.log(JSON.stringify(response));
   * });
   *
   * 该方法会：
   * - 自动生成一个短 ID 作为 message_id（避免重复）
   * - 设置默认的 topic_full_name 和 name 字段
   * - 调用 sendDevicesMessage 接口发送消息
   */
  public sendMessage(message: DeviceActionType): Promise<MessageResultResponse | MessageResultResponseErr> {
    const data: postDevicesMessageRequest = {
      message,
      message_id: generateShortId4(),
      topic_full_name: "t",
      name: "qs"
    }
    return sendDevicesMessage(this.projectId, this.deviceId, data)
  }

  /** 获取当前的影子信息 */
  public getInfo(): DeviceShadowData | null {
    if (this.info == null) {
      console.error("现在是null")
    }
    return this.info;
  }

  public async getSafeInfo(): Promise<DeviceShadowData> {
    await this.ready()
    if (!this.info) {
      throw new Error('数据获取失败')
    }
    return this.info
  }
}

export const DeviceShadowManagerInstance = DeviceShadowManager.getInstance();
